﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using ConfExpert.Utility;
using DevExpress.XtraEditors;
using ConfOrder;


namespace ConfExpert
{
    public partial class ConcurrencySolver :XPopupForm
    {
        public int PK;
        public string TableName;
        public string PKCol;
        DataTable dtResult = null;

        public string Log;

        public ConcurrencySolver(DataRow dr)
        {
            InitializeComponent();
             
            gvDegistirilmis.OptionsSelection.EnableAppearanceFocusedRow = false;
            gvDegistirmekIstedigin.OptionsSelection.EnableAppearanceFocusedRow = false;
            gvSendeki.OptionsSelection.EnableAppearanceFocusedRow = false;

            gvDegistirilmis.OptionsSelection.EnableAppearanceFocusedCell= false;
            gvDegistirmekIstedigin.OptionsSelection.EnableAppearanceFocusedCell = false;
            gvSendeki.OptionsSelection.EnableAppearanceFocusedCell = false;

            gvDegistirilmis.OptionsView.ColumnAutoWidth = false;
            gvDegistirmekIstedigin.OptionsView.ColumnAutoWidth = false;
            gvSendeki.OptionsView.ColumnAutoWidth = false;
            gvSonuc.OptionsView.ColumnAutoWidth = false;

            gvSonuc.Appearance.Row.Font = new System.Drawing.Font(gvSonuc.Appearance.Row.Font, FontStyle.Bold);

            DataRow drSendeki = GetRowData(dr, DataRowVersion.Original);
            DataRow drDegistirilmis = GetRowData(GetCurrentRowInDB(dr), DataRowVersion.Default);            
            DataRow drDegistirmekIstedigin = GetRowData(dr, DataRowVersion.Current);

            gvSendeki.CustomDrawCell += new DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventHandler(gvSendeki_CustomDrawCell);
            gvDegistirilmis.CustomDrawCell += new DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventHandler(gvSendeki_CustomDrawCell);
            gvDegistirmekIstedigin.CustomDrawCell += new DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventHandler(gvSendeki_CustomDrawCell);
            
            TableName = drDegistirmekIstedigin.Table.TableName;
            
            gvSendeki.OptionsBehavior.ReadOnly = true;
            gvDegistirilmis.OptionsBehavior.ReadOnly = true;
            gvDegistirmekIstedigin.OptionsBehavior.ReadOnly = true;

            gvSendeki.OptionsBehavior.Editable = false;
            gvDegistirilmis.OptionsBehavior.Editable = false;
            gvDegistirmekIstedigin.OptionsBehavior.Editable = false;

            List<string> colsToDelete = new List<string>();

            string a = "";
            for (int i = 0; i < drDegistirmekIstedigin.Table.Columns.Count; i++)
            {
                string colName = drDegistirmekIstedigin.Table.Columns[i].ColumnName;
                a += colName+"\r\n";
            }

            string b = "";
            for (int i = 0; i < drDegistirilmis.Table.Columns.Count; i++)
            {
                string colName = drDegistirmekIstedigin.Table.Columns[i].ColumnName;
                b += colName + "\r\n";
            }


            for (int i = 0; i < drDegistirmekIstedigin.Table.Columns.Count; i++)
            {
                string colName = drDegistirmekIstedigin.Table.Columns[i].ColumnName;

                if (colName == drDegistirmekIstedigin.Table.PrimaryKey[0].ColumnName)
                {
                    PK = (int)dr[colName];
                    PKCol = colName;
                    colsToDelete.Add(colName);
                }
                else if (colName == "ModifiedOn")
                {                  
                    //colsToDelete.Add(colName); 
                }
                else if (drDegistirilmis.Table.Columns[colName] == null)
                {
                    colsToDelete.Add(colName);
                }
                else if (drDegistirilmis[colName].ToString().Trim() == drDegistirmekIstedigin[colName].ToString().Trim())
                {
                    colsToDelete.Add(colName);
                }
                else
                {
                    //Çakışan sütunlar
                }
            }


            drSendeki.Table.PrimaryKey = null;
            drDegistirilmis.Table.PrimaryKey = null;
            drDegistirmekIstedigin.Table.PrimaryKey = null;

            foreach (string colName in colsToDelete)
            {
                if (drDegistirilmis.Table.Columns[colName] != null)
                    drDegistirilmis.Table.Columns.Remove(colName);

                if (drSendeki.Table.Columns[colName] != null)
                    drSendeki.Table.Columns.Remove(colName);

                if (drDegistirmekIstedigin.Table.Columns[colName] != null)
                    drDegistirmekIstedigin.Table.Columns.Remove(colName);
            }

            gcSendeki.DataSource = drSendeki.Table;
            gcDegistirmekIstedigin.DataSource = drDegistirmekIstedigin.Table;
            gcDegistirilmis.DataSource = drDegistirilmis.Table;





            dtResult = drDegistirilmis.Table.Clone();
            DataRow drResult = dtResult.NewRow();

            for (int i = 0; i < drDegistirmekIstedigin.Table.Columns.Count; i++)
            {
                drResult[i] = drDegistirmekIstedigin[i];
            }
            if (drResult["ModifiedOn"] != null)
            {
                drResult["ModifiedOn"] = DateTime.Now; 
            }
            dtResult.Rows.Add(drResult);
            gcSonuc.DataSource = dtResult;



            if (gvSendeki.Columns["ModifiedOn"] != null)
            {
                gvSendeki.Columns["ModifiedOn"].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                gvDegistirmekIstedigin.Columns["ModifiedOn"].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                gvDegistirilmis.Columns["ModifiedOn"].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                gvSonuc.Columns["ModifiedOn"].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;

                gvSendeki.Columns["ModifiedOn"].DisplayFormat.FormatString = "dd.MM.yyyy HH:mm:ss";
                gvDegistirmekIstedigin.Columns["ModifiedOn"].DisplayFormat.FormatString = "dd.MM.yyyy HH:mm:ss";
                gvDegistirilmis.Columns["ModifiedOn"].DisplayFormat.FormatString = "dd.MM.yyyy HH:mm:ss";
                gvSonuc.Columns["ModifiedOn"].DisplayFormat.FormatString = "dd.MM.yyyy HH:mm:ss";
            }

            gvSendeki.BestFitColumns();
            gvDegistirilmis.BestFitColumns();
            gvDegistirmekIstedigin.BestFitColumns();
            gvSonuc.BestFitColumns();

            HeaderLabel.Text = string.Format("{0}: {2} | {1}", PKCol , HeaderLabel.Text,PK);
        }
 
        
        void gvSendeki_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
        {
            var current = dtResult.Rows[0][e.Column.FieldName].ToString();

            if (current == e.CellValue.ToString())
                e.Appearance.BackColor = Color.SkyBlue;
            else
                e.Appearance.BackColor = Color.White;
        }

        private DataRow GetCurrentRowInDB(DataRow cr)
        {
            string sql = "select * from " + cr.Table.TableName + " where " + cr.Table.PrimaryKey[0].ColumnName + " = " + cr[cr.Table.PrimaryKey[0].ColumnName];
            DataRow dr = AppSession.DataManager.ExecuteDataTableByQuery(sql).Rows[0];
            return GetRowData(dr, DataRowVersion.Default);
        }

        private DataRow GetRowData(DataRow dr, DataRowVersion RowVersion)
        {
            DataTable dt = dr.Table.Clone();
            DataRow drNew = dt.NewRow();
            for (int i = 0; i < dr.ItemArray.Length; i++)
            {
                drNew[i] = dr[i, RowVersion];
            }
            dt.Rows.Add(drNew);
            return drNew;
        }


        public string Sql = string.Empty;
        private void btnSave_Click(object sender, EventArgs e)
        {
            DialogResult result = XtraMessageBox.Show("Başka birinin yaptığı değişikliğin üzerine yazmış olabilirsiniz. Yaptığınız değişikliği onaylıyor musunuz?", "Dikkat", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

            if (result == System.Windows.Forms.DialogResult.Cancel)
                return;
            else
            {                
                string up1 = "update " + TableName + " set ";
                string up2 = "";

                System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
                
                for (int i = 0; i < dtResult.Columns.Count; i++)
                {
                    DataColumn dc = dtResult.Columns[i];
                    DataRow dr = dtResult.Rows[0];
                    string colName = dc.ColumnName;
                    if (colName == "ModifiedOn") continue;

                    if (dc.DataType == typeof(decimal))
                    {
                        up2 += colName + " = " + ((decimal)dr[colName]).ToString(ci) + ", ";
                    }
                    else
                    {
                        up2 += colName + " = '" + dr[colName].ToString() + "', ";
                    }
                }

                up2 = up2.Remove(up2.Length - 2);
                up2 += " where " + PKCol + " = " + PK.ToString();
                Sql = up1 + up2 + " select * from " + TableName + " where " + PKCol + " = " + PK.ToString();

                this.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.Close();
            }
        }
        
        private void gvDegistirilmis_RowCellClick(object sender, DevExpress.XtraGrid.Views.Grid.RowCellClickEventArgs e)
        {        
            string col = e.Column.FieldName;
            string val = e.CellValue.ToString();

            dtResult.Rows[0][col] = val;

            gvSendeki.Invalidate();
            gvDegistirilmis.Invalidate();
            gvDegistirmekIstedigin.Invalidate();
        }

        private void ConcurrencySolver_FormClosing(object sender, FormClosingEventArgs e)
        {
            int id = LogManager.TakeScreenShot();
            Log = string.Format("{0} | Tablo:{1} | {2}:{3} | ScreenshotId:{4} | SQL:{5} | Result:", "Concurrency Exception", TableName, PKCol, PK, id,Sql);
        }
    }
}